package cn.tedu.luban.order.main.controller;

import cn.tedu.luban.order.main.converter.OrderConverter;
import cn.tedu.luban.order.main.service.OrderService;
import cn.tedu.luban.order.protocol.VO.FrontOrderDetailVO;
import cn.tedu.luban.order.protocol.VO.FrontOrderItemVO;
import cn.tedu.luban.order.protocol.bo.OrderBO;
import cn.tedu.luban.order.protocol.param.OrderConfirmParam;
import cn.tedu.luban.order.protocol.param.OrderCreateParam;
import cn.tedu.luban.order.protocol.param.OrderSignParam;
import cn.tedu.luban.order.protocol.query.FrontOrderListQuery;
import cn.tedu.luban.passport.protocol.jwt.UserPrinciple;
import cn.tedu.luban.passport.sdk.security.LubanSecurityContext;
import cn.tedu.luban.worker.common.enums.WorkerResultEnum;
import com.tedu.inn.protocol.ListRecordTotalBO;
import com.tedu.inn.protocol.exception.BusinessException;
import com.tedu.inn.protocol.model.Result;
import com.tedu.inn.protocol.pager.PagerResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class OrderController {
    @Autowired
    private OrderService orderService;
    /**
     * 师傅抢单接口
     */
    @PostMapping("/order/create")
    public Result<String> orderCreate(@RequestBody OrderCreateParam param)
    throws BusinessException {
        //1. 频繁抢单的拦截 同时补充userId
        reGrabIntercept(param);
        //2. 频繁抢单拦截 没拦住,就是合法抢单 进入业务
        String orderNO=orderService.orderCreate(param);
        return new Result<>(orderNO);
    }
    @Autowired
    private StringRedisTemplate redisTemplate;
    //频繁抢单的拦截 同时补充userId
    private void reGrabIntercept(OrderCreateParam param) throws BusinessException {
        //1. 设计一个key值 由业务数据 userId(登录人id) requestOrderNo组成
        String requestOrderNo=param.getRequestOrderNo();
        Long userId=getUserId();
        param.setUserId(userId);
        String regrabLockKey="luban:order:regrab:"+userId+":"+requestOrderNo;
        //2. 对key值做redis的incr操作 如果是第一次抢返回值是1,连续多次抢 返回值>1
        ValueOperations<String, String> opsForString = redisTemplate.opsForValue();
        Long increment = opsForString.increment(regrabLockKey);
        redisTemplate.expire(regrabLockKey,3, TimeUnit.SECONDS);
        //判断incr结果 >1的都拦截 说明是频繁抢单
        if(increment>1){
            log.error("当前师傅:{},抢单:{},失败",userId,requestOrderNo);
            throw new BusinessException("2001","频繁抢单,请稍后再试");
        }
    }
    private Long getUserId() throws BusinessException {
        UserPrinciple user = LubanSecurityContext.getLoginToken();
        //不一定能拿到登录用户.
        if (user==null){
            throw new BusinessException(WorkerResultEnum.USER_TOKEN_VERIFY_FAILED);
        }
        return user.getId();
    }
    /**
     * 师傅登录查询 未完成订单分页列表
     */
    @Autowired
    private OrderConverter orderConverter;
    @PostMapping("/order/list")
    public Result<PagerResult<FrontOrderItemVO>> orderList(
            @RequestBody FrontOrderListQuery query)throws BusinessException{
        //1. list total需要业务封装查询  pageNo pageSize 入参提供 lastPageIndex 最后一页下标
        Long userId = getUserId();
        query.setUserId(userId);
        ListRecordTotalBO<OrderBO> listBO=orderService.orderList(query);
        //2. 装配分页数据
        PagerResult<FrontOrderItemVO> pageResult = orderConverter.assemblePagerResult(listBO, query);
        return new Result<>(pageResult);
    }
    /**
     * 查询某个师傅的订单详情
     */
    @GetMapping("/order/info")
    public Result<FrontOrderDetailVO> orderDetail(String orderNo)throws BusinessException{
        //1. 从业务层查询orderBO
        OrderBO orderBO=orderService.orderDetail(orderNo);
        //2. 转化成vo封装返回
        FrontOrderDetailVO vo = orderConverter.bo2frontDetailVO(orderBO);
        return new Result<>(vo);
    }
    /**
     * 师傅签到
     */
    @PostMapping("/order/sign")
    public Result<String> orderSign(@RequestBody OrderSignParam param)
        throws BusinessException{
        //1. 调用业务层 出现异常 失败 么有异常就是成功
        orderService.orderSign(param);
        //2. 正常返回数据
        return new Result<>(param.getOrderNo());
    }
    /**
     * 施工确认 施工图片的绑定
     */
    @PostMapping("/order/confirm")
    public Result<String> orderConfirm(@RequestBody OrderConfirmParam param)
        throws BusinessException{
        //1.调用业务层 成功 没反应 没有返回值 失败就抛异常
        orderService.orderConfirm(param);
        //2.正常结束 返回数据
        return new Result<>(param.getOrderNo());
    }
}
